package com.gerfmarquez.nymph;

import java.util.ArrayList;
import java.util.Iterator;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.SharedPreferences.Editor;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.ScaleDrawable;
import android.media.AudioTrack;
import android.os.Bundle;
import android.os.Handler;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.Display;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageButton;
import android.widget.LinearLayout;
import android.widget.Toast;

import com.gerfmarquez.nymph.db.sqlite.DatabaseHelper;
import com.gerfmarquez.nymph.db.sqlite.SongDbAdapter;
import com.gerfmarquez.nymph.db.sqlite.dto.Song;
import com.gerfmarquez.nymph.db.sqlite.dto.SongNoteLength;
import com.gerfmarquez.nymph.music.core.MusicCore;
import com.gerfmarquez.nymph.music.core.PlayNotesThread;
import com.gerfmarquez.nymph.preferences.MusicPreferences;
import com.gerfmarquez.nymph.ui.listeners.OnOpenSelectedMelodyListener;
import com.gerfmarquez.nymph.ui.listeners.OnSaveAsMelodyListener;
import com.gerfmarquez.nymph.ui.listeners.OnSaveSelectedMelodyListener;
import com.gerfmarquez.nymph.ui.seekbar.ImageButtonNew;
import com.gerfmarquez.nymph.ui.seekbar.SpawnNoteView;
import com.gerfmarquez.nymph.ui.seekbar.VerticalSeekBar;
import com.gerfmarquez.nymph.ui.seekbar.ViewInflater;
import com.gerfmarquez.nymph.ui.threads.UpdatePlayStateNotesThread;

public class NymphMelodyCreatorActivity extends Activity {
	
	SharedPreferences shpr;
    static final String TAG= "NymphMelodyCreator";
    byte[][] notesToPlay;
    byte []rhythm;
    LinearLayout secondaryLinearHorizontalLayout;
    Handler handler;
    
    public ArrayList<AudioTrack> audioTracks = new ArrayList<AudioTrack>();
    
    
    /** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(customInflate());
        MusicCore.init(this);
        Display display = getWindowManager().getDefaultDisplay();


        Log.i(TAG,"The height of display is ="+display.getHeight()+" and width is = "+display.getWidth());
//        try {
//        	Thread.sleep(500);
//        }
//        catch(InterruptedException ie) {
//        	
//        }

    }
    @Override
    public void onWindowFocusChanged(boolean hasFocus) {
    	LinearLayout ll = (LinearLayout) findViewById(R.id.mainLinearLayout);
    	Log.i(TAG,"The height of rightLayout is ="+ll.getHeight()+" and width is = "+ll.getWidth());
    	Log.i(TAG,"The height of mainLinearLayout is ="+findViewById(R.id.mainLinearLayout).getHeight()+" and width is = "+findViewById(R.id.mainLinearLayout).getWidth());
    	Drawable drawable = getResources().getDrawable(R.drawable.nymph_background);
    	drawable = new ScaleDrawable(drawable, 0, ll.getWidth(), ll.getHeight()).getDrawable();
    	ll.setBackgroundDrawable(drawable);
    }
    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
    	MenuInflater inflater = getMenuInflater();
    	inflater.inflate(R.menu.menu, menu);
    	return true;
    }
    @Override
    public void onStop() {
    	super.onStop();
    	for(AudioTrack aud: audioTracks) {
    		aud.release();
    	}
    }
    
    
	@Override
	public boolean onOptionsItemSelected(MenuItem item) {
		switch (item.getItemId()) {
		case R.id.preferences:
			// Launch Preference activity
			Intent i = new Intent(NymphMelodyCreatorActivity.this, MusicPreferences.class);
			startActivity(i);
			break;
		case R.id.save:
			showSongListToChooseSave();
			break;
		case R.id.saveAs:
			showInputTextToSaveNameSong();
	    	break;
		case R.id.open:
			showSongListToChooseOpen();
	    	break;
		case R.id.newSong:
			replaceMusicNotesForNewSong();
			break;
		}
		return true;
	}
	@Override
	public void onResume() {
		super.onResume();
		getPrefs();
		Log.e(TAG,"Test RESUME::::::::");
	}
	@Override
	public void onPause() {
		super.onPause();
		Log.e(TAG,"Test PAUSE::::::::");
	}
    
    public void playSongArray(View view) {
//    	notesToPlay = new byte[][]{B,Cs,E,B,F,G};
    	stopSongArray(view);
    	handler = new Handler();
    	rhythm = getNotesRhythm();
    	notesToPlay = MusicCore.getSoundNotesArray(getNotesFromSlideViews());
    	
    	UpdatePlayStateNotesThread uPSN = new UpdatePlayStateNotesThread(this, getVerticalSeekBars(), handler);
		PlayNotesThread pl = new PlayNotesThread(rhythm, audioTracks, notesToPlay, uPSN, this);
		
		uPSN.start();
		pl.start();
		Button playButton = (Button)findViewById(R.id.playButton);
		playButton.setEnabled(false); //in play notes thread it is enabled again after all audio has been written
		uPSN = null;
		pl = null;
		handler = null;
    }
    public void stopSongArray(View view) {
    	Iterator<AudioTrack> it = audioTracks.iterator();
    	while(it.hasNext()) {
    		it.next().release();
    	}
    }
    private void getPrefs() {
        PreferenceManager.setDefaultValues(this, R.xml.preferences, false);

        shpr = PreferenceManager.getDefaultSharedPreferences(this.getApplicationContext());
        try {
        	int bpmTemp = Integer.parseInt(shpr.getString("bpm", "120"));
        	if(bpmTemp >= 80 && bpmTemp <= 350) {
        		
        	}
        	else {
        		Editor editor = shpr.edit();
        		editor.putString("bpm", "120");
        		editor.commit();
        		bpmTemp = 120;
        		Toast t = Toast.makeText(this, "Value for BPM should be between 80 and 350", Toast.LENGTH_LONG);
        		t.show();
        	}
        	MusicCore.setBpm(bpmTemp);
        	
        } catch(NumberFormatException nfe) {
        	MusicCore.setBpm(120);
        }
    }
    
    public int[] getNotesFromSlideViews() {
    	int notesCount = secondaryLinearHorizontalLayout.getChildCount();
    	int[] musicNotes = new int[notesCount];
    	for(int i = 0; i < notesCount; i++) {
    		LinearLayout individualNote = (LinearLayout)secondaryLinearHorizontalLayout.getChildAt(i);
    		VerticalSeekBar vSeekBar = (VerticalSeekBar)individualNote.findViewById(R.id.noteLevel);
    		
    		musicNotes[i] = vSeekBar.getMusicNote();
    	}
    	return musicNotes;
    }
    private ArrayList<VerticalSeekBar> getVerticalSeekBars() {
    	ArrayList<VerticalSeekBar> vs = new ArrayList<VerticalSeekBar>();
    	int notesCount = secondaryLinearHorizontalLayout.getChildCount();
    	for(int i = 0; i < notesCount; i++) {
    		LinearLayout individualNote = (LinearLayout)secondaryLinearHorizontalLayout.getChildAt(i);
    		VerticalSeekBar vSeekBar = (VerticalSeekBar)individualNote.findViewById(R.id.noteLevel);
    		vs.add(vSeekBar);
    	}
    	return vs;
    }
    public byte[] getNotesRhythm() {
    	int notesCount = secondaryLinearHorizontalLayout.getChildCount();
    	byte[] notesRhythm = new byte[notesCount];
    	for(int i = 0; i < notesCount; i++) {
    		LinearLayout individualNote = (LinearLayout)secondaryLinearHorizontalLayout.getChildAt(i);
    		ImageButtonNew rhythmButton = (ImageButtonNew)individualNote.findViewById(R.id.noteRhythm);
    		
    		notesRhythm[i] = Byte.parseByte(rhythmButton.getNoteLength().toString());
    	}
    	return notesRhythm;
    }
    
    
    private LinearLayout customInflate() {
    	
        LinearLayout mainLinearLayout = ViewInflater.getMainLinearLayout(this);
        secondaryLinearHorizontalLayout = (LinearLayout)mainLinearLayout.findViewById(R.id.secondaryLinearLayout);
        
        for(int i = 0; i < 5; i++) {
        	
        	LinearLayout musicNoteLinearVerticalLayout = SpawnNoteView.spawnNoteView(this);
	        
	        secondaryLinearHorizontalLayout.addView(musicNoteLinearVerticalLayout);
        }
        return mainLinearLayout;
    }
    public void changeNoteLengthTap(View view) {
    	Log.d(TAG,"Length button clicked");
//    	ImageButton ib = new ImageButton(this);
//    	ib.setBackgroundDrawable(getResources().getDrawable(R.drawable.seek_thumb_normal));
    	ImageButtonNew button = (ImageButtonNew)view;
    	if(button.getNoteLength().equals("1")) {
    		Log.d(TAG,"Length button clicked: " + "1");
    		button.setNoteLength("2");
    		button.setBackgroundDrawable(getResources().getDrawable(R.drawable.length_half));
    	}
    	else if(button.getNoteLength().equals("2")) {
    		Log.d(TAG,"Length button clicked: " + "2");
    		button.setNoteLength("4");
    		button.setBackgroundDrawable(getResources().getDrawable(R.drawable.length_quarter));
    	}
    	else if(button.getNoteLength().equals("4")) {
    		Log.d(TAG,"Length button clicked: " + "4");
    		button.setNoteLength("8");
    		button.setBackgroundDrawable(getResources().getDrawable(R.drawable.length_eighth));
    	}
    	else if(button.getNoteLength().equals("8")) {
    		Log.d(TAG,"Length button clicked: " + "8");
    		button.setNoteLength("3");
    		button.setBackgroundDrawable(getResources().getDrawable(R.drawable.length_third));
    		
    	}
    	else if(button.getNoteLength().equals("3")) {
    		Log.d(TAG,"Length button clicked: " + "3");
    		button.setNoteLength("1");
    		button.setBackgroundDrawable(getResources().getDrawable(R.drawable.length_whole));
    	}
    }
    
    private ArrayList getMusicNotesFromSong() {
//    	DatabaseHelper dbHelper = new DatabaseHelper(this);
//    	SQLiteDatabase database =dbHelper.getWritableDatabase();
//    	
//    	SongDbAdapter songAdapter = new SongDbAdapter(database);
//		SongNoteLengthDbAdapter sNLDA = new SongNoteLengthDbAdapter(database);
//
//		
//		long idSong = songAdapter.createSong("NombreCancion", 1);
//    	sNLDA.createSongNoteLength(idSong);
//    	
//    	
//    	
//    	dbHelper.close();
    	return null;
    }
    
	public void showInputTextToSaveNameSong() {
	    AlertDialog.Builder builder = new AlertDialog.Builder(this);
	    builder.setTitle("Save melody as:");
	    OnSaveAsMelodyListener onSaveMelodyListener  = new OnSaveAsMelodyListener(this);
	    builder.setCancelable(true);
	    builder.setPositiveButton("Save", onSaveMelodyListener);
	    builder.setNegativeButton("Cancel", null);
	    EditText et = new EditText(this);
	    builder.setView(et);
	    onSaveMelodyListener.editText = et;
	    onSaveMelodyListener.nymph = this;
	    AlertDialog alert = builder.create();
	    alert.show();
	}
    private void showSongListToChooseSave() {
    	DatabaseHelper dbHelper = new DatabaseHelper(this);
    	SQLiteDatabase database =dbHelper.getWritableDatabase();
    	
    	SongDbAdapter songAdapter = new SongDbAdapter(database);
    	ArrayList<Song> songs = songAdapter.fetchAllSongs();
    	
    	dbHelper.close();
    	
    	CharSequence[] items = new CharSequence[songs.size()];
    	
    	for(int i = 0; i < songs.size(); i++) {
    		items[i] = songs.get(i).getSongName();
    		songs.get(i).setItem(i);
    	}
    	
    	AlertDialog.Builder builder = new AlertDialog.Builder(this);
    	
    	builder.setTitle("Choose song to save");
    	OnSaveSelectedMelodyListener onSaveSelect = new OnSaveSelectedMelodyListener(songs,this,this);
    	builder.setItems(items, onSaveSelect);
    	
    	AlertDialog alert = builder.create();
    	alert.show();
    }
    private void showSongListToChooseOpen() {
    	DatabaseHelper dbHelper = new DatabaseHelper(this);
    	SQLiteDatabase database =dbHelper.getWritableDatabase();
    	
    	SongDbAdapter songAdapter = new SongDbAdapter(database);
    	ArrayList<Song> songs = songAdapter.fetchAllSongs();
    	
    	dbHelper.close();
    	
    	CharSequence[] items = new CharSequence[songs.size()];
    	
    	for(int i = 0; i < songs.size(); i++) {
    		items[i] = songs.get(i).getSongName();
    		songs.get(i).setItem(i);
    	}
    	
    	AlertDialog.Builder builder = new AlertDialog.Builder(this);
    	
    	builder.setTitle("Choose song to save");
    	handler = new Handler();
    	OnOpenSelectedMelodyListener onOpenSelect = new OnOpenSelectedMelodyListener(songs,this,this, handler);
    	builder.setItems(items, onOpenSelect);
    	
    	AlertDialog alert = builder.create();
    	alert.show();
    }
    
    public void replaceMusicNotesFromOpenFile(ArrayList<SongNoteLength> songNoteLengths) {
    	LinearLayout secondary = (LinearLayout)findViewById(R.id.secondaryLinearLayout);
    	secondary.removeAllViews();
    	int i = 0;
    	for(SongNoteLength temp: songNoteLengths) {
    		LinearLayout musicNoteLinearVerticalLayout = SpawnNoteView.spawnNoteView(this, temp.getMusicNote(), temp.getNoteLength(), new Handler());
    		LayoutParams layoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.FILL_PARENT);
    		secondary.addView(musicNoteLinearVerticalLayout, i , layoutParams);
    		i++;
    	}
    }
    
    public void replaceMusicNotesForNewSong() {
    	LinearLayout secondary = (LinearLayout)findViewById(R.id.secondaryLinearLayout);
    	secondary.removeAllViews();
    	for(int i = 0; i < 6; i++) {
    		LinearLayout musicNoteLinearVerticalLayout = SpawnNoteView.spawnNoteView(this, 5, 2, new Handler());
    		LayoutParams layoutParams = new LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.FILL_PARENT);
    		secondary.addView(musicNoteLinearVerticalLayout, i , layoutParams);
    	}
    }

//    public void changeColor(View view) {
//    	VerticalSeekBar vs = getVerticalSeekBars().get(0);
////		VerticalSeekBar vs = verticalSeekBars.get(currentNote);
//		Rect bounds = vs.getProgressDrawable().getBounds();
//		int progr = vs.getProgress();
//		int max = vs.getMax();
//		int width = vs.getWidth(); 
//		int height = vs.getHeight();
//
//		vs.setProgressDrawable(this.getResources().getDrawable(R.drawable.myprogress));
//		vs.getProgressDrawable().setBounds(bounds);
//		vs.setMax(max);
//		vs.setProgress(1);
//		vs.setProgress(progr);
//		vs.onSizeChanged(width, height);
//		vs.refreshDrawableState();
//    }
}